#include "DocumentType.h"

DocumentType::DocumentType() {
    replaceWords.push_back(std::string(";"));
    replaceWords.push_back(std::string(":"));
    replaceWords.push_back(std::string("."));
    replaceWords.push_back(std::string(","));
    replaceWords.push_back(std::string("("));
    replaceWords.push_back(std::string(")"));
    replaceWords.push_back(std::string("_"));
    replaceWords.push_back(std::string("-"));
    replaceWords.push_back(std::string("->"));
    replaceWords.push_back(std::string("["));
    replaceWords.push_back(std::string("/*"));
    replaceWords.push_back(std::string("*/"));
    replaceWords.push_back(std::string("/"));
    replaceWords.push_back(std::string("\\"));
    replaceWords.push_back(std::string("\\\\"));
    replaceWords.push_back(std::string("["));
    replaceWords.push_back(std::string("]"));
    replaceWords.push_back(std::string("*"));
    replaceWords.push_back(std::string("#"));
    replaceWords.push_back(std::string("\""));
    replaceWords.push_back(std::string("{"));
    replaceWords.push_back(std::string("}"));
    replaceWords.push_back(std::string("<"));
    replaceWords.push_back(std::string(">"));
    replaceWords.push_back(std::string("="));
    replaceWords.push_back(std::string("+"));
    replaceWords.push_back(std::string("-"));
    replaceWords.push_back(std::string("&"));
    replaceWords.push_back(std::string("!"));
    replaceWords.push_back(std::string("~"));

    for(int i=0;i<EXTRACTOR_getHighestKeywordTypeNumber();i++){
        extractorType.insert(i);
    }

    regcomp(&regex, "^.*\\.txt$", REG_EXTENDED | REG_ICASE);
}

void DocumentType::parse(std::string path, Catalogues* catalog, EXTRACTOR_KeywordList* list) {
    int status;
    std::string fileName = extractFileName(path);
    status = regexec(&regex, fileName.c_str(), (size_t) 0, NULL, 0);
    if (status == 0) {
        parseText(path, catalog);
    } else {
        parseExtractor(path, catalog, list);
    }
}

void DocumentType::parseText(std::string path, Catalogues* catalog) {
    std::set<std::string> values;
    std::vector<std::string> split;
    int (*pf)(int) = tolower;
    std::vector<std::string> listAux;
    std::vector<std::string>::iterator splitIte;
    std::set<std::string>::const_iterator ite;
    std::ifstream configFile;
    configFile.exceptions(std::ifstream::badbit);
    configFile.open(path.c_str(), std::ios::in);
    std::string line;
    values.insert(extractFileName(path));
    getline(configFile, line);
    while (!configFile.eof()) {
        if (!line.empty()) {
            values.insert(line);
            ite = values.begin();
            for (; ite != values.end(); ite++) {
                std::string value = *ite;
                std::transform(value.begin(), value.end(), value.begin(), pf);
                replace(value);
                listAux = StaticUtils::split(value, " ");
                for (splitIte = listAux.begin(); splitIte != listAux.end();) {
                    StaticUtils::trimo(*splitIte);
                    if (StaticUtils::isNumeric(*splitIte) || (*splitIte).empty()) {
                        splitIte = listAux.erase(splitIte);
                    } else {
                        splitIte++;
                    }
                }
                split.insert(split.end(), listAux.begin(), listAux.end());
                matchStopWords(split);
                listAux.clear();
            }
            if (!split.empty())
                catalog->agregarDocumento(path, split);
        }
        line.clear();
        values.clear();
        listAux.clear();
        split.clear();
        getline(configFile, line);
    }
    configFile.close();
}

void DocumentType::parseExtractor(std::string path, Catalogues* catalog, EXTRACTOR_KeywordList* list) {
    EXTRACTOR_KeywordList * aux = NULL;
    aux = list;
    int (*pf)(int) = tolower;
    std::set<std::string>::const_iterator ite;
    std::set<std::string> values;
    std::vector<std::string> split;
    std::vector<std::string>::iterator splitIte;
    std::vector<std::string> listAux;

    extractList(list,values);
    // Ver que hacemos con los numeros de fecha y de numero de cancion
    values.insert(extractFileName(path));
    ite = values.begin();
    for (; ite != values.end(); ite++) {
        std::string value = *ite;
        std::transform(value.begin(), value.end(), value.begin(), pf);
        replace(value);
        listAux = StaticUtils::split(value, " ");
        for (splitIte = listAux.begin(); splitIte != listAux.end();) {
            StaticUtils::trimo(*splitIte);
            if (StaticUtils::isNumeric(*splitIte) || (*splitIte).empty()) {
                splitIte = listAux.erase(splitIte);
            } else {
                splitIte++;
            }
        }
        split.insert(split.end(), listAux.begin(), listAux.end());
        matchStopWords(split);
        listAux.clear();
    }
    if(!split.empty())
        catalog->agregarDocumento(path, split);
}

DocumentType::~DocumentType() {
    regfree(&regex);
}
